Gruppe 1 (I1)

1. semester, efteråret 2002

 

COSS

COmputer Styret Saftblander

 

Rapport

 

 

 

 

 

Gruppen:

                                                Allan H. Michaelsen              01119

                                                Christian Z. Nielsen              01113

                                                Jacob Germundsen              01011

                                                Søren S. Munk                       02847

                                                Tonny Mønster                       01021

 

            Vejleder:                     Poul Zanchetta


Resume:

 

Denne rapport beskriver konstruktionen af en kontrolenhed til en eksisterende saftblander. Enheden skal virke således at blanderen kan dosere vand og saft i en specificeret mængde med forholdet 5:1, så længe at vandtemperaturen ikke er over 16 °C. Der er flere krav til enheden som kan ses i kravspecifikationen.

 Kontrolenheden (vi kalder den COSS) består af flere dele såsom software og hardware, disse igen er delt op i mindre dele og gjort realiserbare derudfra.

 

 Software: Softwaren er skrevet i C++ for den del der kører på Pc’en og der er brugt ABEL til at programmere en PEEL som er en integreret del af hardwaren.

 

 Hardware: Hardwaren er delt op i 2 dele, en analog og en digital. Digitaldelen er bygget op omkring en PEEL og analogdelen er bygget op omkring en dobbelt operationsforstærker.

 


Indholdsfortegnelse

Indhold .................................................................................................................. Afsnit..........Side

Resume: 1..............1

Indholdsfortegnelse. 1..............2

Opgaveformulering. 1..............3

Indledning. 1..............4

Kravspecifikation/Accepttest 2..............4

Strukturering. 3..............4

Implementering. 4..............4

Brugervejledning. 5..............4

Konklusion. 6..............5

Underskrifter 6..............6

Bilag 1 - Elektrisk diagram.. 7..............7

Bilag 2 – Programkode C++. 8............10

AD512DRV.hpp. 10

Incl.hpp. 10

GlobaleVar.hpp. 10

Def.hpp. 11

AD512DRV.cpp. 12

Main.cpp. 15

Func.cpp. 15

Bilag 3 – Programkode ABEL. 9............24

Bilag 4 – Mødereferater 10............26

 

 

 

 

 


Opgaveformulering

 

Der skal udvikles og opbygges en softdrinkautomat baseret på en allerede eksisterende mekanisk opstilling.

 

En softdrink fremstilles ved at en passende mængde saft og vand blandes i en kop på følgende måde:

 

Ved et tryk på startknappen skal koppen køre frem til doseringspositionen, hvis

                         der er en kop i holderen

                         koppen er i startposition

                         vandets temperatur er passende lav

                         resetknappen ikke aktiveres.

 

Koppen skal stoppe i doseringsposition og derefter skal dosering af saft og vand påbegyndes.

Når doseringen af saft og vand er afsluttet, skal koppen køre tilbage til startpositionen.

 

Krav

Automaten skal i øvrigt overholde følgende krav:

                         Der skal være indikering af automatens tilstand og vandets temperatur.

                         Afvigelse af påfyldningsvolumen må højst være 10 %

                         Dosering skal være i forholdet 1 del saft til 5 dele vand, med en nøjagtighed på 10 %

                         Dosering må kun ske når vandets temperatur er 16 °C eller derunder.

                         Omgivelsestemperaturen er 20 °C.

                         Aktivering af resetknappen skal stoppe processen og køre kopholderen tilbage til startposition.

                         Software til styringen skal bestå af et C++ program


Indledning

 

 Rapporten er delt op i afsnit som indeholder punkter såsom resume og konklusion, men også de dokumenter der er gået forud for rapporten selv:

 

 

 Vi har i gruppen delt arbejdet ind på følgende måde:

 

Rapportfletning / Resume / Indledning / Konklusion

·        Allan H Michaelsen

 

Kravspecifikation / Testdokumentation

·        Hele gruppen

 

Strukturering:

·        Allan H Michaelsen

·        Christian Z Nielsen

 

Implementering:

·        De enkelte medlemmer af gruppen har været med til forskellige opgaver. Dette er beskrevet senere i afsnittet implementering.

Kravspecifikation/Accepttest

Strukturering

Implementering

Brugervejledning


Konklusion

 

 Selve Projektet kom godt fra start. Vi lavede kravspecifikationen og struktureringen og fik derudfra konstrueret hardwaren, det meste af det uden problemer.

 Dog skal det nævnes, at de fra kunden leverede standardopstillinger gav visse problemer, som måtte korrigeres før systemerne virkede.

 

 Til digitaldelen af hardwaren skulle vi blandt andet bruge en oscillator til at generere clocksignalet for stepmotorkontrolleren. Til dette ville vi programmere et kredsløb i vores PEEL, som skulle generere dette clocksignal. Det gav dog nogle problemer, da vi ikke kunne få motoren til at køre stabilt med denne opstilling. Som løsning måtte vi sætte en spole ind for at fjerne det meste af den højfrekvente støj som PEEL’en havde på udgangen, og derefter kørte det hele som det skulle.

 

 Ligeledes havde vi på analogdelen et lille problem med forsyningsspændingen, som dog blev løst ved at sætte et par spændingsregulatorer ind for at få en stabil forsyning på +/- 5v. Standardopstillingen havde to forstærkertrin, det første med offset og forstærkning og det andet med slutforstærkning, med en signaludgang til displayet imellem de to trin. Men da vi ikke kører direkte til displayet og i stedet lader computeren klare konverteringen af temperatursignalet, kunne vi nu lave fast forstærkning på første trin og gøre det nemmere at lave offsettet.

 

 I en version 2 skulle kalibreringsprocessen gøres nemmere. Vi har faktisk prøvet med en nemmere måde, men det lykkedes desværre ikke at få det præcist nok.

 Vi tog gennemsnitsværdierne af de eksisterende min og max værdier for begge potmetre, og udnævnte dem til min og max referencer. Så var ideen at finde en værdi for bunden af hver beholder (når flyderen var i bund), og lægge den midlede min værdi til. Så var det ret nemt at kalibrere da man så bare kunne presse flyderne i bund for at få en kalibreringsværdi.

 Vi var ikke tilfredse med den opnåede præcision, da der var for stor spredning på potmetrenes linearitet.

 


Underskrifter

 

 

 

 

__________________________

Allan H Michaelsen

 

 

 

__________________________

            Christian Z Nielsen

 

 

 

__________________________

            Jacob Germundsen

 

 

 

__________________________

            Søren S Munk

 

 

 

__________________________

            Tonny Mønster

 


Bilag 1 - Elektrisk diagram



 


Bilag 2 – Programkode C++

AD512DRV.hpp

// Projekt                  Humusoft AD 512 kort

//

// Fil                          AD512DRV.hpp

// Forfatter               Erik Gross Jensen

//

// Beskrivelse          Header file til funktioner til styring af I/O porte på Humusoft AD512 Data Acquisition Kort

//                                                               

// Version                                1.0 201000

//

 

#ifndef AD512drv_hpp

#define AD512drv_hpp

 

int enableAD512(void);

 

unsigned short AnalogInput(int ch, int range);

 

void AnalogOutput(int ch, int value);

 

int DigitalInput(void);

 

void DigitalOutput(int value);

 

#endif

 

Incl.hpp

// Projekt                  COSS

//

// Fil                          incl.hpp

// Forfatter               Søren S. Munk

//

 

#ifndef COSS_Includes_hpp

#define COSS_Includes_hpp

 

#include "def.hpp"

#include "ad512drv.hpp"

 

#include <iostream>

#include <iomanip>

#include <conio.h>

#include <sys/timeb.h>

#include <windows.h>

#include <process.h>

#include <signal.h>

 

#include <string>

 

using namespace std;

 

#endif

 

GlobaleVar.hpp

// Projekt                  COSS

//

// Fil                          globaleVar.hpp

// Forfatter               Søren S. Munk

//

 

#ifndef COSS_globalVar_hpp

#define COSS_globalVar_hpp

 

//Husk hvad den digitale udgang er

int   digital_udgang   =  0;

bool  resetAktiv       =  false;

int              asaft            =  107;

int   avand            =  98;

 

//Niveau målere

int              max_vand         =  752;                         //6 liter

int              min_vand         =  386;                           //2 liter

int              max_saft         =  2278;                         //6 liter

int              min_saft         =  1794;                          //2 liter

 

#endif

Def.hpp

// Projekt                  COSS

//

// Fil                          def.hpp

// Forfatter               Søren S. Munk & Jacob Germundsen

//

 

#ifndef COSS_Styring_hpp

#define COSS_Styring_hpp

 

////////////////////////////////////

// Type definitioner !! //

////////////////////////////////////

 

 

//0 to 4,294,967,295

typedef unsigned long DWORD;

 

//////////////////////////////////////

// Diverse funktioner !! //

//////////////////////////////////////

 

void clearDisp();

bool doser();

void initialiser(int, char *[]);

void koerSlaede(short);

bool kopStatus(bool,bool);

void moveCursorXY(DWORD,DWORD);

void printTrueFalse(bool);

void printTrueFalse(bool, float);

void reset();

void showStatus();

void signalHandler(int);

void start();

 

///////////////////////////////////

// check functioner !! //

///////////////////////////////////

 

bool checkPos(int);

bool checkKopIHolder();

bool commonChecks(int);

 

///////////////////////////////

// get functioner !! //

///////////////////////////////

 

int              getAnalogIn(short);

bool  getDigitalIn(short,bool);

bool  getKopHolderPos();

bool  getResetAktiv();

int   getSaftNiveau();

float getSaftVolumen();

bool  getStartAktiv();

DWORD getTid( void );

int   getVandNiveau();

float getVandTemp();

float getVandVolumen();

 


///////////////////////////////

// set functioner !! //

//////////////////////////////

 

void setAnalogOut(short,short);

void setDigitalOut(short,bool);

void setTextColor(unsigned long);

 

///////////////////////////

// Konstanter !! //

//////////////////////////

 

#define PRIORITY                                    HIGH_PRIORITY_CLASS

#define myProg                                                       "a:\\Coss.exe"

#define myProg_path                                              "\"a:\\Coss.exe\""

 

//CONSOLE DISPLAY

#define CLEAR                                                        "                                         "

#define HORLINE                                                     "\xCD"      //"\xC4"

#define VERLINE                                                     "\xBA"     //"\xB3"

#define TOPLEFT                                                    "\xDA"     //"\xDA"

#define TOPRIGHT                                  "\xBF"      //"\xBF"

#define BUTTOMLEFT                                             "\xC0"      //"\xC0"

#define BUTTOMRIGHT                                           "\xD9"      //"\xD9"

#define TOPMID                                                       "\xC2"      //"\xC2"

#define BUTTOMMID                                               "\xC1"      //"\xC1"

#define XOFFSET                                                    15

#define YOFFSET                                                   3

#define STATUS_TEXT_OFFSET            12

#define CONWIDTH                                 50

#define CONMID                                                      25

#define TEXT_COLOR                                             FOREGROUND_BLUE | !FOREGROUND_INTENSITY

#define BACK_COLOR                                           BACKGROUND_INTENSITY

#define FOREGROUND_BLACK    FOREGROUND_BLUE & FOREGROUND_RED & FOREGROUND_GREEN

#define FOREGROUND_YELLOW           FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY

 

//divers konstanter

#define POSITION_START                      1

#define POSITION_DOS                          0

#define TOM_KOP                                                   1

#define BRUGT_KOP                                              0

#define FREM                                                          0

#define TILBAGE                                                     1

#define DAOFFSET                                 2045        //2022

#define TEMPOFFSET                                             0.22

#define AFDRYP_TID                                              2000

 

//bit på digital kanal OUT

#define STEPMOTOR_HOLD_L               1

#define STEPMOTOR_DIR                       2

#define VENTIL_SAFT                                            4

#define VENTIL_VAND                                           8

#define TAEND_2DEC4                                           16

#define DECODER_1                                               32

#define DECODER_2                                               64

#define DECODER_3                                               128

 

//bit på digital kanal IN

#define START_AKTIV                                           1                              //PIN 12

#define RESET_AKTIV                                            2                              //PIN 13

#define POS_START                                               4                              //PIN 14

#define POS_DOS                                                   8                              //PIN 15

#define KopIHolder                                  16                            //PIN 16

 

//Analog kanaler IN

#define VAND                                                         0                              //PIN 1

#define SAFT                                                          1                              //PIN 2

#define TEMP                                                          2                              //PIN 3

 

#endif

 

AD512DRV.cpp

// Projekt                  Humusoft AD 512 kort

//

// Fil                          AD512DRV.cpp

// Forfatter               Erik Gross Jensen

//

// Beskrivelse          Funktioner til styring af I/O porte på Humusoft AD512 Data Acquisition Kort

//

// Ændret                 Søren Munk, Udskriver fejlbeskeder

//

// Version        2.0 201000

//

 

 

#include <conio.h>

#include <windows.h>

#include <stdio.h>

#include <process.h>

 

#define IOENABLE 0x100

 

// base address for the AD512 kort

#define AD512BASE 0x300

#define IOLENGTH 8

/*****************************************************************************

 

enableAD512

 

enable direct access to I/O ports

 

Input: ingen

Output: 0 = enable ok,

error otherwise

 

/****************************************************************************/

 

int enableAD512(void)

{

                OSVERSIONINFO ver;

                HANDLE drvhandle;

                unsigned long cb;

                unsigned message[2];

                int ok;

 

 

                /* Test the Win32 platform we run on. If this is not Windows NT/2000, we can

                just return success because I/O access is already allowed. */

 

                ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

                GetVersionEx(&ver);

                if (ver.dwPlatformId != VER_PLATFORM_WIN32_NT)

                                return(0);

 

                /* Open the handle to the DIRECTHW device driver. The driver must be installed for this to succeed.

If this fails the board cannot be accessed. */

                drvhandle = CreateFile("\\\\.\\DIRECTHW", GENERIC_READ | GENERIC_WRITE, 0, NULL,

                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

                if (drvhandle == INVALID_HANDLE_VALUE) {

                                printf(" FEJL: enableAD512():\tKan ikke finde DIRECTHW!\n");

                                printf("\a\n Mulige grunde:\n\tHumusoft AD512 er ikke installeret eller \

                                                    \n\tdu har ikke nok rettigheder som bruger.   \

                                                    \n\tFor at installere AD512 find setup.bat i \

                                                                \tt:\\install\\humusoft\\setup\\ \n");

                                return(-1);

                }

 

                /* Send a request to the driver. This consists of the request code (IOENABLE)

                and two-word message containing I/O address and range to be enabled. */

 

                message[0] = AD512BASE;

                message[1] = IOLENGTH;

                ok = DeviceIoControl(drvhandle, IOENABLE, message, sizeof(message), NULL, 0, &cb, NULL);

 

 

                /* We are done - close the handle and return. */

 

                CloseHandle(drvhandle);

                if (!ok) {

                                printf("\a FEJL: enableAD512():\tKan ikke initialisere Humusoft AD512! (%i)\n",ok);

                                printf("\n Mulig grund:\n\tDriver fejl");

                }

                return(ok ? 0 : -2);

}

 

 

 

/*****************************************************************************

 

ANALOGINPUT

læser analog værdi fra analog input kanal

 

Input: channel: kanalnummer fra 0-7

range: 0 = 0 - 5 volt

1 = +/- 5 volt

2 = 0 - 10 volt

3 = +/- 10 volt

 

Output: den læste værdi 12 bit som en int fra 0-4095

 

;****************************************************************************/

 

unsigned short AnalogInput(int ch, int range)

{

 

                _outp(AD512BASE+5, ch | (range<<3) | 0x40);     // select channel and range; start the conversion

                while (_inp(AD512BASE+5) & 0x80);              // wait until conversion finishes

 

                return(_inpw(AD512BASE) & 0xFFF);              // return converted value, masking unused bits

}

 

 

 

/*****************************************************************************

 

ANALOGOUTPUT

skriv en værdi til analog output

 

Input channel: kanalnummer 0-1

value: værdi til output 12 bit 0-4095 (+/- 5 volt)

Output: none

 

;****************************************************************************/

 

void AnalogOutput (int ch, int value)

{

                unsigned short adresse;

                adresse = AD512BASE + 2*ch;

                _outpw(adresse, value);                 // write the value to D/A converter

                _outp(AD512BASE+4, 0);                  // update converter output

 

}

 

 

 

/*****************************************************************************

 

DIGITALINPUT

læser de digitale indgange

 

Input: none

Output: den læste værdi som en byte hvor hver bit repræsentere en

af de 8 digitale indgange

 

;****************************************************************************/

 

int DigitalInput(void)

{

 

                return(_inp(AD512BASE+7));                     // return value from digital input

}

 

 

 

/*****************************************************************************

 

DIGITALOUTPUT

skriver en byte til de digitale udgange

 

Input: byte hvor hver bit repræsentere en af de 8 digitale udgange

Output: none

 

;****************************************************************************/

 

void DigitalOutput(int value)

{

 

                _outp(AD512BASE+7, value);                     // write the value to digital output

 

}

 

Main.cpp

// Projekt  COSS

//

// Fil                          main.cpp

//

 

#include "incl.hpp"

 

void main(int numargs, char *args[]) {

                clearDisp();

                signal(SIGINT, signalHandler);

                signal(SIGABRT, signalHandler);

                if (SetPriorityClass(GetCurrentProcess(), PRIORITY))

                                cout << " PRIORITY = " << PRIORITY << " set!" << endl;

 

                if (enableAD512()==0) {

                                setDigitalOut(TAEND_2DEC4, false);

                                cout << " Humusoft AD512 fundet og klar til brug" <<  endl;

                                initialiser(numargs, args);

                                clearDisp();

                                reset();

                                start();

                }

                else {

                                cout << endl << " Humusoft AD512 blev ikke fundet!" << endl << " Tryk p\x86 en vilk\x86rlig tast for at afslutte";

                                getch();

                }

}

 

Func.cpp

// Projekt                  COSS

//

// Fil                          func.cpp

//

 

#include "incl.hpp"

#include "globaleVar.hpp"

 

void clearDisp() {   

                setTextColor(BACK_COLOR | FOREGROUND_BLACK);

                system("cls");

}

 

bool doser() {

                moveCursorXY(XOFFSET,YOFFSET+STATUS_TEXT_OFFSET);

                cout << " Doserer vand og saft!";

                if (commonChecks(POSITION_DOS)) {

                                kopStatus(true, BRUGT_KOP);

                                DWORD vandSkaenkeTid = ((((getVandVolumen() - 14.7) *1000 / -2424) * 1000)*5/6);

                                DWORD saftSkaenkeTid = ((((getSaftVolumen() - 14.7) *1000 / -2424) * 1000)*1/6);

                                DWORD vandEndeligTid = (getTid() + vandSkaenkeTid);

                                DWORD saftEndeligTid = (getTid() + saftSkaenkeTid);

                                setDigitalOut(VENTIL_VAND, true);

                                setDigitalOut(VENTIL_SAFT, true);

 

                                bool saftDoseret = false;

                                bool vandDoseret = false;

 

                                unsigned int startTid = getTid();

                                while (!vandDoseret) {

                                                DWORD tid = getTid();

                                                if ((tid >= saftEndeligTid) & !saftDoseret) {

                                                                setDigitalOut(VENTIL_SAFT, false);

                                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+1);

                                                                cout << " Saft doseret (" << (tid-startTid) << " ms)" << CLEAR << endl;

                                                                saftDoseret = true;

                                                }

                                                if (tid >= vandEndeligTid) {

                                                                setDigitalOut(VENTIL_VAND, false);

                                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+2);

                                                                cout << " Vand doseret (" << (tid-startTid) << " ms)" << CLEAR << endl;

                                                                vandDoseret = true;

                                                }

                                                if (getResetAktiv() || getDigitalIn(KopIHolder, false)) {

                                                                reset();

                                                                return false;

                                                }

                                                showStatus();

                                }

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+3);

                                cout << " Afdrypning i " << (AFDRYP_TID /1000) << " sekunder";

 

                                vandEndeligTid = getTid()+AFDRYP_TID;

                                while (getTid() <= vandEndeligTid)

                                                showStatus();

 

                                return true;

                }

                return false;

}

 

void initialiser(int numargs, char *args[]) {

                if (numargs == 1) {

                                char svar;

                                cout << "\n Kalibrering? (j/n): ";

                                svar = tolower(getche());

                                if (svar == 'j') {

 

                                                cout << "\n VAND 2 L! (";

                                                getch();

                                                min_vand = getVandNiveau();

                                                avand = -1*min_vand;

                                                cout << min_vand << ")";

 

                                                cout << "\n VAND 6 L! (";

                                                getch();

                                                avand += max_vand = getVandNiveau();

                                                cout << max_vand << ")";

 

                                                avand /= 4;

 

                                                cout << "\n SAFT 2 L! (";

                                                getch();

                                                min_saft = getSaftNiveau();

                                                asaft = -1*min_saft;

                                                cout << min_saft << ")";

 

                                                cout << "\n SAFT 6 L! (";

                                                getch();

                                                asaft += max_saft = getSaftNiveau();

                                                cout << min_saft << ")";

 

                                                asaft /= 4;

                                }

                }

                else if (numargs = 7) {

                                int i = 1;

                                asaft = atoi(args[i++]);

                                avand = atoi(args[i++]);

                                min_saft = atoi(args[i++]);

                                max_saft = atoi(args[i++]);

                                min_vand = atoi(args[i++]);

                                max_vand = atoi(args[i++]);

                                cout << min_vand << max_vand << min_saft << max_saft << endl;

                }

}

 

void koerSlaede(short dir) {

                setDigitalOut(STEPMOTOR_DIR, dir);

                setDigitalOut(STEPMOTOR_HOLD_L, true);

}

 

bool kopStatus(bool gemme, bool status) {

                static bool kop_status = BRUGT_KOP;

                if (gemme)

                                kop_status = status;

                return(kop_status);

}

 

void moveCursorXY(DWORD X, DWORD Y) {

                COORD point = {X,Y};

 

                HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

 

                SetConsoleCursorPosition(hConsole, point);

}

 

void printTrueFalse(bool value) {

                if (value) {

                                setTextColor(BACK_COLOR | FOREGROUND_GREEN | FOREGROUND_INTENSITY);

                                cout << "Ja ";

                                setTextColor(BACK_COLOR | TEXT_COLOR);

                }

                else {

                                setTextColor(BACK_COLOR | FOREGROUND_RED);

                                cout << "Nej";

                                setTextColor(BACK_COLOR | TEXT_COLOR);

                }

}

 

void printTrueFalse(bool value, float out) {

                if (value)

                                setTextColor(BACK_COLOR | FOREGROUND_GREEN | FOREGROUND_INTENSITY);

                else

                                setTextColor(BACK_COLOR | FOREGROUND_RED);

 

                cout << setprecision(1) << setiosflags(ios::fixed | ios::showpoint ) << out;

                setTextColor(BACK_COLOR | TEXT_COLOR);

}

 

void reset() {

                bool onOff = (digital_udgang & TAEND_2DEC4) / TAEND_2DEC4;

                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET);

                cout << " Reset!" << CLEAR;

                setDigitalOut(VENTIL_VAND, false);

                setDigitalOut(VENTIL_SAFT, false);

                setDigitalOut(STEPMOTOR_HOLD_L, false);         

 

                DWORD sleepTid = getTid();

                DWORD blinkTid = 0;

                while (sleepTid+AFDRYP_TID >= getTid()) {

                                if (getTid() > blinkTid+100) {

                                                onOff = !onOff;

                                                setDigitalOut(TAEND_2DEC4,onOff);

                                                blinkTid = getTid();

                                }

                                showStatus();

                }

 

                if (!checkPos(POSITION_START)) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+1);

                                cout << " K\x9Brer til POS_START" << CLEAR << endl;

                                koerSlaede(TILBAGE);

                                while (!checkPos(POSITION_START)) {

                                                if (getTid() > blinkTid+100) {

                                                                onOff = !onOff;

                                                                setDigitalOut(TAEND_2DEC4,onOff);

                                                                blinkTid = getTid();

                                                }

                                                if (getResetAktiv()) {

                                                                reset();

                                                                break;

                                                }

                                                showStatus();

                                }

                }

                setDigitalOut(STEPMOTOR_HOLD_L, false);

                setDigitalOut(TAEND_2DEC4,true);

}

 

void showStatus() {

                int linienr = 0;

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout<< " COSS status:";

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                setTextColor(BACK_COLOR | FOREGROUND_BLACK);

                cout << TOPLEFT;

                for (int i = 1; i<CONWIDTH; i++) {

                                if (i == CONMID)

                                                cout << TOPMID;

                                else

                                                cout << HORLINE;

                }

                cout << TOPRIGHT;

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Kopholderposition        ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3 "; setTextColor(BACK_COLOR | TEXT_COLOR); getKopHolderPos(); moveCursorXY(XOFFSET+CONWIDTH, YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

                                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Kop i kopholder?        ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3 "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse(checkKopIHolder()); moveCursorXY(XOFFSET+CONWIDTH, YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Skiftet kop?            ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3 "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse(kopStatus(false, false));       moveCursorXY(XOFFSET+CONWIDTH, YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

                                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Startknap aktiv?        ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3 "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse(getStartAktiv()); moveCursorXY(XOFFSET+CONWIDTH, YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Resetknap aktiv?        ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3   "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse( getResetAktiv()); moveCursorXY(XOFFSET+CONWIDTH,YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

                                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3";

moveCursorXY(XOFFSET+CONWIDTH, YOFFSET+linienr-1); cout << VERLINE;

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Vand temperatur         ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3   "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse( (getVandTemp()<=16.0), getVandTemp()); cout << " \xF8\C "; moveCursorXY(XOFFSET+CONWIDTH,YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

                moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Vandm\x91ngde              ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3   "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse( (getVandVolumen() >= 2), getVandVolumen()); cout << " L "; moveCursorXY(XOFFSET+CONWIDTH,YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << VERLINE; setTextColor(BACK_COLOR | TEXT_COLOR); cout << " Saftm\x91ngde              ";

setTextColor(BACK_COLOR | FOREGROUND_BLACK); moveCursorXY(XOFFSET+CONMID,YOFFSET+linienr-1); cout << "\xB3   "; setTextColor(BACK_COLOR | TEXT_COLOR); printTrueFalse( (getSaftVolumen() >= 2), getSaftVolumen()); cout << " L "; moveCursorXY(XOFFSET+CONWIDTH,YOFFSET+linienr-1); setTextColor(BACK_COLOR | FOREGROUND_BLACK); cout << VERLINE;

moveCursorXY(XOFFSET, YOFFSET+linienr++);

                cout << BUTTOMLEFT;

                for (int i = 1; i<CONWIDTH; i++) {

                                if (i == CONMID)

                                                cout << BUTTOMMID;

                                else

                                                cout << HORLINE;

                }

                cout << BUTTOMRIGHT << endl;

}

 

void signalHandler(int signal) {

                char sasaft[5];

                _itoa(asaft, sasaft, 10);

                char savand[5];

                _itoa(avand, savand, 10);

                char smin_saft[5];

                _itoa(min_saft, smin_saft, 10);

                char smax_saft[5];

                _itoa(max_saft, smax_saft, 10);

                char smin_vand[5];

                _itoa(min_vand, smin_vand, 10);

                char smax_vand[5];

                _itoa(max_vand, smax_vand, 10);

                DigitalOutput(0);

                _spawnl(_P_NOWAIT, myProg, myProg_path, sasaft, savand, smin_saft, smax_saft, smin_vand, smax_vand, NULL);

                exit(-1);

}

 

void start() {

                while (true) {

                                clearDisp();

                                while (!getStartAktiv()) {

                                                showStatus();

                                                if (resetAktiv = getResetAktiv()) {

                                                                reset();

                                                                clearDisp();

                                                }

                                                if (_kbhit()) {

                                                                char c = _getch();

                                                                if (c == 'S')

                                                                                break;

                                                                else if (c == 'K')

                                                                                kopStatus(true, true);

                                                }

                                }

 

                                showStatus();

                                if (!commonChecks(POSITION_START))

                                                reset();

 

                                else if (!(resetAktiv = getResetAktiv())) {

                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET);

                                                cout << " K\x9Brer til POS_DOS" << CLEAR << endl;

                                                koerSlaede(FREM);

                                                while (!checkPos(POSITION_DOS)) {

                                                                if ((resetAktiv = getResetAktiv()) || !checkKopIHolder()) {

                                                                                reset();

                                                                                break;

                                                                }

                                                                showStatus();

                                                }

 

                                                setDigitalOut(STEPMOTOR_HOLD_L, false);

 

                                                if (!resetAktiv)

                                                                doser();

 

                                                if (!resetAktiv) {

                                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET);

                                                                cout << " K\x9Brer til POS_START" << CLEAR << endl;

                                                                koerSlaede(TILBAGE);

                                                                while (!checkPos(POSITION_START)) {

                                                                                if ((resetAktiv = getResetAktiv()) || !checkKopIHolder()) {

                                                                                                reset();

                                                                                                break;

                                                                                }

                                                                                showStatus();

                                                                }

                                                                setDigitalOut(STEPMOTOR_HOLD_L, false);

                                                }

                                }

                }

}

 

///////////////////////////////////

// check funktioner !! //

///////////////////////////////////

 

bool checkPos(int position) {

 

                if (position != POSITION_START & position != POSITION_DOS) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET);

                                cout << "FEJL: checPos():\tUlovlig position: " << position << endl;

                                return false;

                }

 

                else if (getDigitalIn(POS_START, true)) {

                                setDigitalOut(DECODER_1, false);

                                setDigitalOut(DECODER_2, false);

                                if (position == POSITION_START) {

                                                return true;

                                }

                                else

                                                return false;

                }

 

                else if (getDigitalIn(POS_DOS, true)) {

                                setDigitalOut(DECODER_1, false);

                                setDigitalOut(DECODER_2, true);

                                if (position == POSITION_DOS) {

                                                return true;

                                }

                                else

                                                return false;

                }

 

                else if ((digital_udgang & STEPMOTOR_DIR) / STEPMOTOR_DIR == TILBAGE) {

                                setDigitalOut(DECODER_1+DECODER_2,true);

                                return false;

                }

 

                else {

                                setDigitalOut(DECODER_1,true);

                                setDigitalOut(DECODER_2,false);

                                return false;

                }

}

 

bool checkKopIHolder() {

                if (!getDigitalIn(KopIHolder, true)) {

                                if (checkPos(POSITION_START)) {

                                                kopStatus(true, TOM_KOP);

                                }

                                return false;

                }

                return true;

}

 

bool commonChecks(int position) {

                bool value = true;

                int linienr = 2;

                if (!checkKopIHolder()) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                cout << " FEJL: CommonChecks():\tDer er ikke nogen kop i kopholderen";

                                value = false;

 

                }

                if ( checkPos(POSITION_START) ) {

                                if (!(position==POSITION_START)) {

                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                                cout << " FEJL: CommonChecks():\tKopholder er ikke i POS_START";

                                                value = false;

                                }

                                else if (getVandTemp() > 16.0 ) {

                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                                cout << " FEJL: CommonChecks():\tTemperaturen er over 16 \xF8\C";

                                                value = false;

                                }

                }

                else {

                                if ( !checkPos(POSITION_DOS)) {

                                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                                cout << " FEJL: CommonChecks():\tKopholder er ikke i POS_DOS";

                                                value = false;

                                }

                }

                if (getResetAktiv()) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                cout << " FEJL: CommonChecks():\tReset er aktiv";

                                value = false;

                }

                if (kopStatus(false, false) == BRUGT_KOP) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                cout << " FEJL: CommonChecks():\tKoppen har v\x91ret brugt!";

                                value = false;

                }

                if (getVandVolumen() < 2.0) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                cout << " FEJL: CommonChecks():\tDer er for lidt vand!";

                                value = false;

                }

                if (getSaftVolumen() < 2.0) {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET+linienr++);

                                cout << " FEJL: CommonChecks():\tDer er for lidt saft!";

                                value = false;

                }                              

                return value;

}

 

///////////////////////////////

// get funktioner !! //

///////////////////////////////

 

int getAnalogIn(short kanal) {

                if (kanal > 7 || kanal < 0) {

                                cout << " FEJL: getAnalogIn():\tKanalen eksisterer ikke: " << kanal;

                                return (-1);

                }

                return AnalogInput(kanal, 0);

}

 

bool getDigitalIn(short kanal, bool value) {

                int tal = DigitalInput();

                tal = tal & kanal;

                if (tal > 0)

                                tal = tal / kanal;

                return (tal == value );

}

 

bool getKopHolderPos() {

                if (checkPos(POSITION_START)) {

                                cout << "Start            ";

                                return true;

                }

                else if (checkPos(POSITION_DOS)) {

                                cout << "Dosering         ";

                                return true;

                }

                else if ((digital_udgang & STEPMOTOR_DIR) / STEPMOTOR_DIR == TILBAGE) {

                                cout << "Dosering -> Start";

                                return false;

                }

                else {

                                cout << "Start -> Dosering";

                                return false;

                }

}

 

bool getResetAktiv() {  //Aktiv lav

                return (getDigitalIn(RESET_AKTIV, false) );

}

 

int getSaftNiveau() {

                return (getAnalogIn(SAFT) );

}

 

float getSaftVolumen() {

                float saftVol = (((getSaftNiveau()-min_saft)+asaft*2.0)/asaft);

                if (saftVol < 0)

                                return 0;

                else

                                return saftVol;

}

 

bool getStartAktiv() {  //Aktiv lav

                return (getDigitalIn(START_AKTIV, false) );

}

 

DWORD getTid() {

                struct __timeb64 timebuffer;

 

                _ftime64( &timebuffer );

                return (timebuffer.time * 1000 + timebuffer.millitm);

}

 

int getVandNiveau() {

                return (getAnalogIn(VAND) );

}

 

float getVandTemp() {

                float temp = (getAnalogIn(TEMP) );

                float tempCelcius = (temp * 49.054/4096) - TEMPOFFSET;

                if (tempCelcius > 16)

                                setDigitalOut(DECODER_3,true);

                else

                                setDigitalOut(DECODER_3,false);

 

                setAnalogOut(0, DAOFFSET + temp/2);

                if (tempCelcius < 0)

                                return 0;

                return tempCelcius;

}

 

float getVandVolumen() {

                float vandVol = ((getVandNiveau()-min_vand)+avand*2.0)/avand;

                if (vandVol < 0)

                                return 0;

                else

                                return vandVol;

}

 

///////////////////////////////

// set funktioner !! //

///////////////////////////////

 

void setDigitalOut(short kanal, bool value) {

                if (((kanal & digital_udgang) / kanal) == value) {}

                else {

                                if (value == true) {

                                                digital_udgang = digital_udgang | kanal;

                                }

                                else {

                                                digital_udgang = digital_udgang - kanal;

                                }

                                if (digital_udgang < 0)

                                                digital_udgang = 0;

                }

                DigitalOutput(digital_udgang);

}

 

void setAnalogOut(short kanal, short value) {

                if ((value >= 0) & (value < 4096))

                                AnalogOutput (kanal, value);

                else {

                                moveCursorXY(XOFFSET, YOFFSET+STATUS_TEXT_OFFSET);

                                cout << " FEJL: setAnalogOut(): value er forkert" << endl;

                }

}

 

void setTextColor(DWORD dwAttributes) {

                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), dwAttributes);

}

 


Bilag 3 – Programkode ABEL

MODULE Stpmtrst

 

declarations

clock, hold, dir               PIN 1, 2, 3;

 

Q1..Q2                                      PIN 23,22 istype 'reg';

 

ibuf                                           PIN 6;

obuf                                          PIN 19 istype 'com';

 

iinv1, iinv2                                  PIN 4,5;

inv1 , inv2                                  PIN 20,21 istype 'com';

 

taend_2dec4                              PIN 8;

ibit1,ibit2,ibit3                PIN 9,10,11;

obit1,obit2,obit3,obit4,obit5         PIN 18..14 istype 'com';

 

x,c = .x.,.c.;

 

QSTATE =[Q1,Q2];

s00 = [0,0];

s01 = [0,1];

s11 = [1,1];

s10 = [1,0];

 

equations

QSTATE.CLK = clock;

QSTATE.OE  = [1,1];

 

"2-4 decoder

obit1 = (!ibit2 & !ibit1) & taend_2dec4;

obit2 = (!ibit2 & ibit1) & taend_2dec4;

obit3 = (ibit2 & !ibit1) & taend_2dec4;

obit4 = (ibit2 & ibit1) & taend_2dec4;

 

"vaeske varm

obit5 = ibit3;

 

"inverter

inv1 = !iinv1;

inv2 = !iinv2;

 

"buffer

obuf = ibuf;

 

state_diagram QSTATE

state s00:" a=0; b=0;

            if dir & hold then s01 else

                        if hold then s10

                                    else s00;

 

state s01:" a=0; b=1;

            if dir & hold then s11 else

                        if hold then s00

                                    else s01;

 

state s11:" a=1; b=1;

            if dir & hold then s10 else

                        if hold then s01

                                    else s11;

 

state s10:" a=1; b=0;

            if dir & hold then s00 else

                        if hold then s11

                                    else s10;

 

test_vectors

([   hold,    dir,  clock] -> [QSTATE,Q1,Q2])

                                    [x,x,0]   ->         [s00,0,0];

                                    [0,x,c]   ->         [s00,0,0];

 

                                    [1,1,c] ->           [s01,0,1];

                                    [0,x,c] ->           [s01,0,1];

                                    [1,1,c] ->           [s11,1,1];

                                    [0,x,c] ->           [s11,1,1];

                                    [1,1,c] ->           [s10,1,0];

                                    [0,x,c] ->           [s10,1,0];

                                    [1,1,c] ->           [s00,0,0];

                                    [0,x,c] ->           [s00,0,0];

 

                                    [1,0,c] ->           [s10,1,0];

                                    [0,x,c] ->           [s10,1,0];

                                    [1,0,c] ->           [s11,1,1];

                                    [0,x,c] ->           [s11,1,1];

                                    [1,0,c] ->           [s01,0,1];

                                    [0,x,c] ->           [s01,0,1];

                                    [1,0,c] ->           [s00,0,0];

                                    [0,x,c] ->           [s00,0,0];

 

test_vectors

([ibit2,ibit1,ibit3,taend_2dec4] -> [obit1,obit2,obit3,obit4,obit5])

                                    [0,0,0,1] ->        [1,0,0,0,0];

                                    [0,0,1,1] ->        [1,0,0,0,1];

                                    [0,1,0,1] ->        [0,1,0,0,0];

                                    [1,0,1,1] ->        [0,0,1,0,1];

                                    [1,1,0,1] ->        [0,0,0,1,0];

                                    [1,1,0,0] ->        [0,0,0,0,0];

                                    [1,1,1,0] ->        [0,0,0,0,1];

END

 


Bilag 4 – Mødereferater

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 11.09.02 - Uge 37

Møde nummer: 01

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 16.09.02 - Uge 38

Møde nummer: 02

 

 


 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 18.09.02 – Uge 38

Møde nummer: 03

 

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 23.09.02 – Uge 39

Møde nummer: 04

 

 

 


 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 30.09.02 – Uge 40

Møde nummer: 05

 

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 07.10.02 – Uge 41

Møde nummer: 06

 

 


 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 21.10.02 – Uge 43

Møde nummer: 07

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 28.10.02 – Uge 44

Møde nummer: 08

 

 

 

 

 


 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 04.11.02 – Uge 45

Møde nummer: 09

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 11.11.02 – Uge 46

Møde nummer: 10

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 18.11.02 – Uge 47

Møde nummer: 11

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 25.11.02 – Uge 48

Møde nummer: 12

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 09.12.02 – Uge 50

Møde nummer: 13

 

 

 

 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 12.12.02 – Uge 50

Møde nummer: 14

 

 


 

Mødereferat for projekt

Gruppe 1, semester I1

Dato: 16.12.02 – Uge 51

Møde nummer: 15